//
//  main.cpp
//  Android jni
//
//  Created by Zhaoyi on 12-9-19.
//  Copyright (c) 2012年 HappyBluefin. All rights reserved.
//

#include "AppDelegate.h"
#include "platform/android/jni/JniHelper.h"

#include "cocos2d.h"

#include <jni.h>
#include <android/log.h>

#define  LOG_TAG    "main"
#define  LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)

using namespace cocos2d;

extern "C"
{
static char* jstringTostring(JNIEnv* env, jstring jstr)
{
    char* rtn = NULL;
    jclass clsstring = env->FindClass("java/lang/String");

    jstring strencode = env->NewStringUTF("utf-8");

    jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");

    jbyteArray barr= (jbyteArray)env->CallObjectMethod(jstr, mid, strencode);
    jsize alen = env->GetArrayLength(barr);
    jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);
    if (alen > 0)
    {
        rtn = (char*)malloc(alen + 1);
        memcpy(rtn, ba, alen);
        rtn[alen] = 0;
    }

    env->ReleaseByteArrayElements(barr, ba, 0);

    return rtn;
}

jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
    LOGD("JNI_OnLoad() start");

    JniHelper::setJavaVM(vm);

    LOGD("JNI_OnLoad() end");

    return JNI_VERSION_1_4;
}

void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv* env, jobject thiz, jint w, jint h)
{
    LOGD("Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit() start");

    LOGD("Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit", "w=%d", w);
    LOGD("Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit", "h=%d", h);

    if (!CCDirector::sharedDirector()->getOpenGLView())
    {
        CCEGLView *view = CCEGLView::sharedOpenGLView();
        view->setFrameSize(w, h);

        AppDelegate *pAppDelegate = new AppDelegate();
        CCApplication::sharedApplication()->run();
    }
    else
    {
        ccDrawInit();
        ccGLInvalidateStateCache();
        
        CCShaderCache::sharedShaderCache()->reloadDefaultShaders();
        CCTextureCache::reloadAllTextures();
        CCNotificationCenter::sharedNotificationCenter()->postNotification(EVNET_COME_TO_FOREGROUND, NULL);
        CCDirector::sharedDirector()->setGLDefaultValues(); 
    }

    LOGD("Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit() end");
}

void showLeaderBoard(const char* boardName)
{
    LOGD("showLeaderBoard() start");

    if (boardName != NULL)
    {
        LOGD("showLeaderBoard(): boardName: %s", boardName);

        JNIEnv* env = NULL;
        JavaVM *vm = NULL;
        int state;

        vm = JniHelper::getJavaVM();
        if (vm != NULL)
        {
            state = vm->GetEnv((void**)&env, JNI_VERSION_1_4);
            if (state < 0)
            {
                LOGE("showLeaderBoard(): GetEnv() failed");
                LOGD("showLeaderBoard() end");
                return;
            }

            jclass cls = env->FindClass("com/happybluefin/tapburstfree/common/jni/ScoreloopJni");
            if (!cls)
            {
                LOGE("showLeaderBoard(): FindClass() failed");
                LOGD("showLeaderBoard() end");
                return;
            }

            jmethodID showLeaderBoard = env->GetStaticMethodID(cls, "showLeaderBoard", "(Ljava/lang/String;)V");
            if (!showLeaderBoard)
            {
                LOGE("showLeaderBoard(): GetStaticMethodID() failed");
                LOGD("showLeaderBoard() end");
                return;
            }

            jstring param = env->NewStringUTF(boardName);
            env->CallStaticObjectMethod(cls, showLeaderBoard, param);
        }
    }
    else
    {
        LOGD("showLeaderBoard(): boardName is NULL");
    }

    LOGD("showLeaderBoard() end");
}

void reportScore(const char* boardName, int score)
{
    LOGD("reportScore() start");

    if (boardName != NULL)
    {
        LOGD("reportScore(): boardName: %s", boardName);
        LOGD("reportScore(): score: %i", score);

        JNIEnv* env = NULL;
        JavaVM *vm = NULL;
        int state;

        vm = JniHelper::getJavaVM();
        if (vm != NULL)
        {
            state = vm->GetEnv((void**)&env, JNI_VERSION_1_4);
            if (state < 0)
            {
                LOGE("reportScore(): GetEnv() failed");
                LOGD("reportScore() end");
                return;
            }

            jclass cls = env->FindClass("com/happybluefin/tapburstfree/common/jni/ScoreloopJni");
            if (!cls)
            {
                LOGE("reportScore(): FindClass() failed");
                LOGD("reportScore() end");
                return;
            }

            jmethodID reportScore = env->GetStaticMethodID(cls, "reportScore", "(Ljava/lang/String;I)V");
            if (!reportScore)
            {
                LOGE("reportScore(): GetStaticMethodID() failed");
                LOGD("reportScore() end");
                return;
            }

            jstring param = env->NewStringUTF(boardName);
            env->CallStaticObjectMethod(cls, reportScore, param, score);
        }
    }
    else
    {
        LOGD("reportScore(): boardName is NULL");
    }

    LOGD("reportScore() end");
}

void shareToSinaWeibo(const char* text)
{
    LOGD("shareToSinaWeibo() start");

    if (text != NULL)
    {
        LOGD("shareToSinaWeibo(): text: %s", text);

        JNIEnv* env = NULL;
        JavaVM *vm = NULL;
        int state;

        vm = JniHelper::getJavaVM();
        if (vm != NULL)
        {
            state = vm->GetEnv((void**)&env, JNI_VERSION_1_4);
            if (state < 0)
            {
                LOGE("shareToSinaWeibo(): GetEnv() failed");
                LOGD("shareToSinaWeibo() end");
                return;
            }

            jclass cls = env->FindClass("com/happybluefin/tapburstfree/common/jni/SinaWeiboJni");
            if (!cls)
            {
                LOGE("shareToSinaWeibo(): FindClass() failed");
                LOGD("shareToSinaWeibo() end");
                return;
            }

            jmethodID shareToSinaWeibo = env->GetStaticMethodID(cls, "share", "(Ljava/lang/String;)V");
            if (!shareToSinaWeibo)
            {
                LOGE("shareToSinaWeibo(): GetStaticMethodID() failed");
                LOGD("shareToSinaWeibo() end");
                return;
            }

            jstring param = env->NewStringUTF(text);
            env->CallStaticObjectMethod(cls, shareToSinaWeibo, param);
        }
    }
    else
    {
        LOGD("shareToSinaWeibo(): text is NULL");
    }

    LOGD("shareToSinaWeibo() end");
}

void shareToTencentWeibo(const char* text)
{
    LOGD("shareToTencentWeibo() start");

    if (text != NULL)
    {
        LOGD("shareToTencentWeibo(): text: %s", text);

        JNIEnv* env = NULL;
        JavaVM *vm = NULL;
        int state;

        vm = JniHelper::getJavaVM();
        if (vm != NULL)
        {
            state = vm->GetEnv((void**)&env, JNI_VERSION_1_4);
            if (state < 0)
            {
                LOGE("shareToTencentWeibo(): GetEnv() failed");
                LOGD("shareToTencentWeibo() end");
                return;
            }

            jclass cls = env->FindClass("com/happybluefin/tapburstfree/common/jni/TencentWeiboJni");
            if (!cls)
            {
                LOGE("shareToTencentWeibo(): FindClass() failed");
                LOGD("shareToTencentWeibo() end");
                return;
            }

            jmethodID shareToTencentWeibo = env->GetStaticMethodID(cls, "share", "(Ljava/lang/String;)V");
            if (!shareToTencentWeibo)
            {
                LOGE("shareToTencentWeibo(): GetStaticMethodID() failed");
                LOGD("shareToTencentWeibo() end");
                return;
            }

            jstring param = env->NewStringUTF(text);
            env->CallStaticObjectMethod(cls, shareToTencentWeibo, param);
        }
    }
    else
    {
        LOGD("shareToTencentWeibo(): text is NULL");
    }

    LOGD("shareToTencentWeibo() end");
}

void gotoUrl(const char* url)
{
    LOGD("gotoUrl() start");

    if (url != NULL)
    {
        LOGD("gotoUrl(): url: %s", url);

        JNIEnv* env = NULL;
        JavaVM *vm = NULL;
        int state;

        vm = JniHelper::getJavaVM();
        if (vm != NULL)
        {
            state = vm->GetEnv((void**)&env, JNI_VERSION_1_4);
            if (state < 0)
            {
                LOGE("gotoUrl(): GetEnv() failed");
                LOGD("gotoUrl() end");
                return;
            }

            jclass cls = env->FindClass("com/happybluefin/tapburstfree/common/jni/WebBrowserJni");
            if (!cls)
            {
                LOGE("gotoUrl(): FindClass() failed");
                LOGD("gotoUrl() end");
                return;
            }

            jmethodID gotoUrl = env->GetStaticMethodID(cls, "gotoUrl", "(Ljava/lang/String;)V");
            if (!gotoUrl)
            {
                LOGE("gotoUrl(): GetStaticMethodID() failed");
                LOGD("gotoUrl() end");
                return;
            }

            jstring param = env->NewStringUTF(url);
            env->CallStaticObjectMethod(cls, gotoUrl, param);
        }
    }
    else
    {
        LOGD("gotoUrl(): url is NULL");
    }

    LOGD("gotoUrl() end");
}

const char* getAndroidLocalizedString(const char* index)
{
    LOGD("getAndroidLocalizedString() start");

    char* ret = NULL;

    if (index != NULL)
    {
        LOGD("getAndroidLocalizedString(): index: %s", index);

        JNIEnv* env = NULL;
        JavaVM *vm = NULL;
        int state;

        vm = JniHelper::getJavaVM();
        if (vm != NULL)
        {
            state = vm->GetEnv((void**)&env, JNI_VERSION_1_4);
            if (state < 0)
            {
                LOGE("getAndroidLocalizedString(): GetEnv() failed");
                LOGD("getAndroidLocalizedString() end");
                return ret;
            }

            jclass cls = env->FindClass("com/happybluefin/tapburstfree/common/jni/LanguageJni");
            if (!cls)
            {
                LOGE("getAndroidLocalizedString(): FindClass() failed");
                LOGD("getAndroidLocalizedString() end");
                return ret;
            }

            jmethodID getLocalizedString = env->GetStaticMethodID(cls, "getLocalizedString", "(Ljava/lang/String;)Ljava/lang/String;");
            if (!getLocalizedString)
            {
                LOGE("getAndroidLocalizedString(): GetStaticMethodID() failed");
                LOGD("getAndroidLocalizedString() end");
                return ret;
            }

            jstring param = env->NewStringUTF(index);
            jstring str = (jstring)env->CallStaticObjectMethod(cls, getLocalizedString, param);

            ret = jstringTostring(env, str);
        }
    }
    else
    {
        LOGD("getAndroidLocalizedString(): url is NULL");
    }

    LOGD("getAndroidLocalizedString() end");

    return ret;
}


bool isChinese()
{
    LOGD("isChinese() start");

    bool ret = false;

    JNIEnv* env = NULL;
    JavaVM *vm = NULL;
    int state;

    vm = JniHelper::getJavaVM();
    if (vm != NULL)
    {
        state = vm->GetEnv((void**)&env, JNI_VERSION_1_4);
        if (state < 0)
        {
            LOGE("isChinese(): GetEnv() failed");
            LOGD("isChinese() end");
            return ret;
        }

        jclass cls = env->FindClass("com/happybluefin/tapburstfree/common/jni/LanguageJni");
        if (!cls)
        {
            LOGE("isChinese(): FindClass() failed");
            LOGD("isChinese() end");
            return ret;
        }

        jmethodID isChinese = env->GetStaticMethodID(cls, "isChinese", "()Z");
        if (!isChinese)
        {
            LOGE("isChinese(): GetStaticMethodID() failed");
            LOGD("isChinese() end");
            return ret;
        }

        ret = (jstring)env->CallStaticObjectMethod(cls, isChinese);
    }

    LOGD("isChinese() end");

    return ret;
}

const char* getCountryCode()
{
    LOGD("getCountryCode() start");

    char* ret = NULL;

    JNIEnv* env = NULL;
    JavaVM *vm = NULL;
    int state;

    vm = JniHelper::getJavaVM();
    if (vm != NULL)
    {
        state = vm->GetEnv((void**)&env, JNI_VERSION_1_4);
        if (state < 0)
        {
            LOGE("getCountryCode(): GetEnv() failed");
            LOGD("getCountryCode() end");
            return ret;
        }

        jclass cls = env->FindClass("com/happybluefin/tapburstfree/common/jni/LanguageJni");
        if (!cls)
        {
            LOGE("getCountryCode(): FindClass() failed");
            LOGD("getCountryCode() end");
            return ret;
        }

        jmethodID getCountryCode = env->GetStaticMethodID(cls, "getCountryCode", "()Ljava/lang/String;");
        if (!getCountryCode)
        {
            LOGE("getCountryCode(): GetStaticMethodID() failed");
            LOGD("getCountryCode() end");
            return ret;
        }

        jstring str = (jstring)env->CallStaticObjectMethod(cls, getCountryCode);

        ret = jstringTostring(env, str);
    }

    LOGD("getCountryCode() end");

    return ret;
}

const char* getLanguageCode()
{
    LOGD("getLanguageCode() start");

    char* ret = NULL;

    JNIEnv* env = NULL;
    JavaVM *vm = NULL;
    int state;

    vm = JniHelper::getJavaVM();
    if (vm != NULL)
    {
        state = vm->GetEnv((void**)&env, JNI_VERSION_1_4);
        if (state < 0)
        {
            LOGE("getLanguageCode(): GetEnv() failed");
            LOGD("getLanguageCode() end");
            return ret;
        }

        jclass cls = env->FindClass("com/happybluefin/tapburstfree/common/jni/LanguageJni");
        if (!cls)
        {
            LOGE("getLanguageCode(): FindClass() failed");
            LOGD("getLanguageCode() end");
            return ret;
        }

        jmethodID getLanguageCode = env->GetStaticMethodID(cls, "getLanguageCode", "()Ljava/lang/String;");
        if (!getLanguageCode)
        {
            LOGE("getLanguageCode(): GetStaticMethodID() failed");
            LOGD("getLanguageCode() end");
            return ret;
        }

        jstring str = (jstring)env->CallStaticObjectMethod(cls, getLanguageCode);

        ret = jstringTostring(env, str);
    }

    LOGD("getLanguageCode() end");

    return ret;
}

int umengGetParamValue(const char* name)
{
    LOGD("umengGetParamValue() start");

    int ret = 0;

    if (name != NULL)
    {
        LOGD("umengGetParamValue(): name: %s", name);

        JNIEnv* env = NULL;
        JavaVM *vm = NULL;
        int state;

        vm = JniHelper::getJavaVM();
        if (vm != NULL)
        {
            state = vm->GetEnv((void**)&env, JNI_VERSION_1_4);
            if (state < 0)
            {
                LOGE("umengGetParamValue(): GetEnv() failed");
                LOGD("umengGetParamValue() end");
                return ret;
            }

            jclass cls = env->FindClass("com/happybluefin/tapburstfree/common/jni/UmengJni");
            if (!cls)
            {
                LOGE("umengumengGetParamValue(): FindClass() failed");
                LOGD("umengGetParamValue() end");
                return ret;
            }

            jmethodID getParamValue = env->GetStaticMethodID(cls, "getParamValue", "(Ljava/lang/String;)I");
            if (!getParamValue)
            {
                LOGE("umengGetParamValue(): GetStaticMethodID() failed");
                LOGD("umengGetParamValue() end");
                return ret;
            }

            jstring param = env->NewStringUTF(name);
            ret = (int)env->CallStaticObjectMethod(cls, getParamValue, param);

            LOGD("umengGetParamValue(): %s is %i", name, ret);
        }
    }
    else
    {
        LOGD("umengGetParamValue(): name is NULL");
    }

    LOGD("umengGetParamValue() end");

    return ret;
}

void umengCustomEvent(const char* name, const char* value)
{
    LOGD("umengCustomEvent() start");

    if ((name != NULL) && (value != NULL))
    {
        LOGD("umengCustomEvent(): name: %s", name);
        LOGD("umengCustomEvent(): value: %s", value);

        JNIEnv* env = NULL;
        JavaVM *vm = NULL;
        int state;

        vm = JniHelper::getJavaVM();
        if (vm != NULL)
        {
            state = vm->GetEnv((void**)&env, JNI_VERSION_1_4);
            if (state < 0)
            {
                LOGE("umengCustomEvent(): GetEnv() failed");
                LOGD("umengCustomEvent() end");
                return;
            }

            jclass cls = env->FindClass("com/happybluefin/tapburstfree/common/jni/UmengJni");
            if (!cls)
            {
                LOGE("umengCustomEvent(): FindClass() failed");
                LOGD("umengCustomEvent() end");
                return;
            }

            jmethodID customEvent = env->GetStaticMethodID(cls, "customEvent", "(Ljava/lang/String;Ljava/lang/String;)V");
            if (!customEvent)
            {
                LOGE("umengCustomEvent(): GetStaticMethodID() failed");
                LOGD("umengCustomEvent() end");
                return;
            }

            jstring param1 = env->NewStringUTF(name);
            jstring param2 = env->NewStringUTF(value);
            env->CallStaticObjectMethod(cls, customEvent, param1, param2);
        }
    }
    else
    {
        LOGD("umengCustomEvent(): name or value is NULL");
    }

    LOGD("umengCustomEvent() end");
}

void openAdsMogoOffer()
{
    LOGD("openAdsMogoOffer() start");

    JNIEnv* env = NULL;
    JavaVM *vm = NULL;
    int state;

    vm = JniHelper::getJavaVM();
    if (vm != NULL)
    {
        state = vm->GetEnv((void**)&env, JNI_VERSION_1_4);
        if (state < 0)
        {
            LOGE("openAdsMogoOffer(): GetEnv() failed");
            LOGD("openAdsMogoOffer() end");
            return;
        }

        jclass cls = env->FindClass("com/happybluefin/tapburstfree/common/jni/AdsMogoJni");
        if (!cls)
        {
            LOGE("openAdsMogoOffer(): FindClass() failed");
            LOGD("openAdsMogoOffer() end");
            return;
        }

        jmethodID openOffer = env->GetStaticMethodID(cls, "openOffer", "()V");
        if (!openOffer)
        {
            LOGE("openAdsMogoOffer(): GetStaticMethodID() failed");
            LOGD("openAdsMogoOffer() end");
            return;
        }

        env->CallStaticObjectMethod(cls, openOffer);
    }

    LOGD("openAdsMogoOffer() end");
}

}